package com.leyou.user.service;

import com.leyou.common.utils.NumberUtils;
import com.leyou.user.mapper.UserMapper;
import com.leyou.user.pojo.User;
import com.leyou.user.utils.CodecUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    // 消息队列
    @Autowired
    private AmqpTemplate amqpTemplate;

    // 操作redis的对象
    @Autowired
    private StringRedisTemplate redisTemplate;


    // 定义一个定量标记redis里的key
    private static final String KEY_PREFIX = "user:code:phone";

    // 日志
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    /**
     * 校验
     *
     * @param data
     * @param type
     * @return
     */
    public Boolean checkData(String data, Integer type) {
        User user = new User();
        if (type == 1) {
            user.setUsername(data);
        } else if (type == 2) {
            user.setPhone(data);
        } else {
            return null;
        }

        return this.userMapper.selectCount(user) == 0;
    }

    /**
     * 短信验证码发送的service
     *
     * @param phone
     * @return
     */
    public Boolean sendVerifyCode(String phone) {
        // 生成6位的验证码
        String code = NumberUtils.generateCode(6);
        try {
            // 发送短信
            Map<String, String> msg = new HashMap<>();
            msg.put("phone", phone);
            msg.put("code", code);
            // 发送发送短信的消息队列（交换机名称,topic,内容）
            this.amqpTemplate.convertAndSend("leyou.sms.exchange", "sms.verify.code", msg);
            // 将code存入redis,并且设置5分钟的有效时间
            this.redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 5, TimeUnit.MINUTES);
            return true;
        } catch (Exception e) {
            logger.error("发送短信失败,手机号:{},验证码:{}", phone, code);
            return false;
        }
    }

    /**
     * 用户注册方法
     *
     * @param user 用户对象
     * @param code 短信验证码
     * @return
     */
    public Boolean register(User user, String code) {
        if (StringUtils.isBlank(code)) {
            return null;
        }
        String Checkcode = this.redisTemplate.opsForValue().get(KEY_PREFIX + user.getPhone());

        // 根据手机号判断验证码是否和redis里放的一致
        if (!StringUtils.equals(Checkcode, code)) {
            return null;
        }

        //生成盐
        String salt = CodecUtils.generateSalt();
        user.setSalt(salt);
        // 对密码进行加密+盐
        user.setPassword(CodecUtils.md5Hex(user.getPassword(), salt));

        // 防止注入设置idnull,mybatis自增会自动创建
        user.setId(null);
        user.setCreated(new Date());

        // 添加到数据库,和插入数据库的结果集对比返回布尔类型的result
        Boolean result = this.userMapper.insertSelective(user) == 1;
        if (result) {
            // 注册成功。删除redis里的记录，节省内存啦
            this.redisTemplate.delete(KEY_PREFIX + user.getPhone());
        }
        return result; // 返回结果集
    }

    /**
     * 根据用户名密码查询用户
     *
     * @param username
     * @param password
     * @return
     */
    public User queryService(String username, String password) {
        User user = new User();
        user.setUsername(username);
        User result = this.userMapper.selectOne(user);
        if (result == null) {
            return null;
        }
        // 从数据库中获取盐result.getSalt(), 然后跟传过来的明文密码一起组合得出来加密的密码
        // 和数据库里的密码进行对比看是否一致
        String md5Result = CodecUtils.md5Hex(password, result.getSalt());

        if (!result.getPassword().equals(md5Result)) {
            return null;
        }

        // 说明用户名密码都正确
        return user;
    }

//    public static void main(String[] args) {
//        String s = CodecUtils.md5Hex("111111", "1af0fb826279457b94e19be63b575f6c");
//        System.out.println(s);
//    }
}
